home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 001-025 / 002 / microemacs / basic.c < prev    next >
C/C++ Source or Header  |  1995-03-13  |  9KB  |  285 lines

  1. /*
  2.  * The routines in this file move the cursor around on the screen. They
  3.  * compute a new value for the cursor, then adjust ".". The display code
  4.  * always updates the cursor location, so only moves between lines, or
  5.  * functions that adjust the top line in the window and invalidate the
  6.  * framing, are hard.
  7.  */
  8. #include        <stdio.h>
  9. #include        "ed.h"
  10.  
  11. /*
  12.  * Move the cursor to the
  13.  * beginning of the current line.
  14.  * Trivial.
  15.  */
  16. gotobol(f, n)
  17. {
  18.         curwp->w_doto  = 0;
  19.         return (TRUE);
  20. }
  21.  
  22. /*
  23.  * Move the cursor backwards by "n" characters. If "n" is less than zero call
  24.  * "forwchar" to actually do the move. Otherwise compute the new cursor
  25.  * location. Error if you try and move out of the buffer. Set the flag if the
  26.  * line pointer for dot changes.
  27.  */
  28. backchar(f, n)
  29. register int    n;
  30. {
  31.         register LINE   *lp;
  32.  
  33.         if (n < 0)
  34.                 return (forwchar(f, -n));
  35.         while (n--) {
  36.                 if (curwp->w_doto == 0) {
  37.                         if ((lp=lback(curwp->w_dotp)) == curbp->b_linep)
  38.                                 return (FALSE);
  39.                         curwp->w_dotp  = lp;
  40.                         curwp->w_doto  = llength(lp);
  41.                         curwp->w_flag |= WFMOVE;
  42.                 } else
  43.                         curwp->w_doto--;
  44.         }
  45.         return (TRUE);
  46. }
  47.  
  48. /*
  49.  * Move the cursor to the end of the current line. Trivial. No errors.
  50.  */
  51. gotoeol(f, n)
  52. {
  53.         curwp->w_doto  = llength(curwp->w_dotp);
  54.         return (TRUE);
  55. }
  56.  
  57. /*
  58.  * Move the cursor forwwards by "n" characters. If "n" is less than zero call
  59.  * "backchar" to actually do the move. Otherwise compute the new cursor
  60.  * location, and move ".". Error if you try and move off the end of the
  61.  * buffer. Set the flag if the line pointer for dot changes.
  62.  */
  63. forwchar(f, n)
  64. register int    n;
  65. {
  66.         if (n < 0)
  67.                 return (backchar(f, -n));
  68.         while (n--) {
  69.                 if (curwp->w_doto == llength(curwp->w_dotp)) {
  70.                         if (curwp->w_dotp == curbp->b_linep)
  71.                                 return (FALSE);
  72.                         curwp->w_dotp  = lforw(curwp->w_dotp);
  73.                         curwp->w_doto  = 0;
  74.                         curwp->w_flag |= WFMOVE;
  75.                 } else
  76.                         curwp->w_doto++;
  77.         }
  78.         return (TRUE);
  79. }
  80.  
  81. /*
  82.  * Goto the beginning of the buffer. Massive adjustment of dot. This is
  83.  * considered to be hard motion; it really isn't if the original value of dot
  84.  * is the same as the new value of dot. Normally bound to "M-<".
  85.  */
  86. gotobob(f, n)
  87. {
  88.         curwp->w_dotp  = lforw(curbp->b_linep);
  89.         curwp->w_doto  = 0;
  90.         curwp->w_flag |= WFHARD;
  91.         return (TRUE);
  92. }
  93.  
  94. /*
  95.  * Move to the end of the buffer. Dot is always put at the end of the file
  96.  * (ZJ). The standard screen code does most of the hard parts of update.
  97.  * Bound to "M->".
  98.  */
  99. gotoeob(f, n)
  100. {
  101.         curwp->w_dotp  = curbp->b_linep;
  102.         curwp->w_doto  = 0;
  103.         curwp->w_flag |= WFHARD;
  104.         return (TRUE);
  105. }
  106.  
  107. /*
  108.  * Move forward by full lines. If the number of lines to move is less than
  109.  * zero, call the backward line function to actually do it. The last command
  110.  * controls how the goal column is set. Bound to "C-N". No errors are
  111.  * possible.
  112.  */
  113. forwline(f, n)
  114. {
  115.         register LINE   *dlp;
  116.  
  117.         if (n < 0)
  118.                 return (backline(f, -n));
  119.         if ((lastflag&CFCPCN) == 0)             /* Reset goal if last   */
  120.                 curgoal = curcol;               /* not C-P or C-N       */
  121.         thisflag |= CFCPCN;
  122.         dlp = curwp->w_dotp;
  123.         while (n-- && dlp!=curbp->b_linep)
  124.                 dlp = lforw(dlp);
  125.         curwp->w_dotp  = dlp;
  126.         curwp->w_doto  = getgoal(dlp);
  127.         curwp->w_flag |= WFMOVE;
  128.         return (TRUE);
  129. }
  130.  
  131. /*
  132.  * This function is like "forwline", but goes backwards. The scheme is exactly
  133.  * the same. Check for arguments that are less than zero and call your
  134.  * alternate. Figure out the new line and call "movedot" to perform the
  135.  * motion. No errors are possible. Bound to "C-P".
  136.  */
  137. backline(f, n)
  138. {
  139.         register LINE   *dlp;
  140.  
  141.         if (n < 0)
  142.                 return (forwline(f, -n));
  143.         if ((lastflag&CFCPCN) == 0)             /* Reset goal if the    */
  144.                 curgoal = curcol;               /* last isn't C-P, C-N  */
  145.         thisflag |= CFCPCN;
  146.         dlp = curwp->w_dotp;
  147.         while (n-- && lback(dlp)!=curbp->b_linep)
  148.                 dlp = lback(dlp);
  149.         curwp->w_dotp  = dlp;
  150.         curwp->w_doto  = getgoal(dlp);
  151.         curwp->w_flag |= WFMOVE;
  152.         return (TRUE);
  153. }
  154.  
  155. /*
  156.  * This routine, given a pointer to a LINE, and the current cursor goal
  157.  * column, return the best choice for the offset. The offset is returned.
  158.  * Used by "C-N" and "C-P".
  159.  */
  160. getgoal(dlp)
  161. register LINE   *dlp;
  162. {
  163.         register int    c;
  164.         register int    col;
  165.         register int    newcol;
  166.         register int    dbo;
  167.  
  168.         col = 0;
  169.         dbo = 0;
  170.         while (dbo != llength(dlp)) {
  171.                 c = lgetc(dlp, dbo);
  172.                 newcol = col;
  173.                 if (c == '\t')
  174.                         newcol |= 0x07;
  175.                 else if (c<0x20 || c==0x7F)
  176.                         ++newcol;
  177.                 ++newcol;
  178.                 if (newcol > curgoal)
  179.                         break;
  180.                 col = newcol;
  181.                 ++dbo;
  182.         }
  183.         return (dbo);
  184. }
  185.  
  186. /*
  187.  * Scroll forward by a specified number of lines, or by a full page if no
  188.  * argument. Bound to "C-V". The "2" in the arithmetic on the window size is
  189.  * the overlap; this value is the default overlap value in ITS EMACS. Because
  190.  * this zaps the top line in the display window, we have to do a hard update.
  191.  */
  192. forwpage(f, n)
  193. register int    n;
  194. {
  195.         register LINE   *lp;
  196.  
  197.         if (f == FALSE) {
  198.                 n = curwp->w_ntrows - 2;        /* Default scroll.      */
  199.                 if (n <= 0)                     /* Forget the overlap   */
  200.                         n = 1;                  /* if tiny window.      */
  201.         } else if (n < 0)
  202.                 return (backpage(f, -n));
  203. #if     CVMVAS
  204.         else                                    /* Convert from pages   */
  205.                 n *= curwp->w_ntrows;           /* to lines.            */
  206. #endif
  207.         lp = curwp->w_linep;
  208.         while (n-- && lp!=curbp->b_linep)
  209.                 lp = lforw(lp);
  210.         curwp->w_linep = lp;
  211.         curwp->w_dotp  = lp;
  212.         curwp->w_doto  = 0;
  213.         curwp->w_flag |= WFHARD;
  214.         return (TRUE);
  215. }
  216.  
  217. /*
  218.  * This command is like "forwpage", but it goes backwards. The "2", like
  219.  * above, is the overlap between the two windows. The value is from the ITS
  220.  * EMACS manual. Bound to "M-V". We do a hard update for exactly the same
  221.  * reason.
  222.  */
  223. backpage(f, n)
  224. register int    n;
  225. {
  226.         register LINE   *lp;
  227.  
  228.         if (f == FALSE) {
  229.                 n = curwp->w_ntrows - 2;        /* Default scroll.      */
  230.                 if (n <= 0)                     /* Don't blow up if the */
  231.                         n = 1;                  /* window is tiny.      */
  232.         } else if (n < 0)
  233.                 return (forwpage(f, -n));
  234. #if     CVMVAS
  235.         else                                    /* Convert from pages   */
  236.                 n *= curwp->w_ntrows;           /* to lines.            */
  237. #endif
  238.         lp = curwp->w_linep;
  239.         while (n-- && lback(lp)!=curbp->b_linep)
  240.                 lp = lback(lp);
  241.         curwp->w_linep = lp;
  242.         curwp->w_dotp  = lp;
  243.         curwp->w_doto  = 0;
  244.         curwp->w_flag |= WFHARD;
  245.         return (TRUE);
  246. }
  247.  
  248. /*
  249.  * Set the mark in the current window to the value of "." in the window. No
  250.  * errors are possible. Bound to "M-.".
  251.  */
  252. setmark(f, n)
  253. {
  254.         curwp->w_markp = curwp->w_dotp;
  255.         curwp->w_marko = curwp->w_doto;
  256.         mlwrite("[Mark set]");
  257.         return (TRUE);
  258. }
  259.  
  260. /*
  261.  * Swap the values of "." and "mark" in the current window. This is pretty
  262.  * easy, bacause all of the hard work gets done by the standard routine
  263.  * that moves the mark about. The only possible error is "no mark". Bound to
  264.  * "C-X C-X".
  265.  */
  266. swapmark(f, n)
  267. {
  268.         register LINE   *odotp;
  269.         register int    odoto;
  270.  
  271.         if (curwp->w_markp == NULL) {
  272.                 mlwrite("No mark in this window");
  273.                 return (FALSE);
  274.         }
  275.         odotp = curwp->w_dotp;
  276.         odoto = curwp->w_doto;
  277.         curwp->w_dotp  = curwp->w_markp;
  278.         curwp->w_doto  = curwp->w_marko;
  279.         curwp->w_markp = odotp;
  280.         curwp->w_marko = odoto;
  281.         curwp->w_flag |= WFMOVE;
  282.         return (TRUE);
  283. }
  284.  
  285.